
import java.util.BitSet;

/*
 ********************************************************************************** 
  Classe para as instruções do tipo R
 **********************************************************************************
 */
public class instrucaoR implements instrucao{
  public static final int OPCODE_R = 0;
  public static final int FUNCT_SLL = 0;  
  public static final int FUNCT_JR = 8;
  public static final int FUNCT_MULT = 24;
  public static final int FUNCT_DIV = 26;
  public static final int FUNCT_ADD = 32;            /***********Constantes com os OPCodes de cada instrução, para referência futura*************/
  public static final int FUNCT_SUB = 34;                  
  public static final int FUNCT_AND = 36;
  public static final int FUNCT_OR = 37;
  public static final int FUNCT_SLT = 42;
  
  private String nome;    //Nome da instrução, para mostrar na tela
  private int funct;      //Valor do campo funct em base 10
  private registrador rS; //Registrador rS
  private registrador rT; //Registrador rT
  private registrador rD; //Registrador rD
  private int shmt;       //Valor do shift amount em base 10

  
  //Construtor, identifica qual a instrução e faz a inicialização de acordo
  public instrucaoR(BitSet b) {
    BitSet campoFunct = b.get(0,6);
    this.funct = Integer.parseInt(funcoes.bitSetStr(campoFunct, 6, true),2);
    this.funct = Integer.parseInt(this.funct + "",16);
    BitSet endRs = b.get(21,26);
    int numRs = Integer.parseInt(funcoes.bitSetStr(endRs, 5, true),2);
    this.rS = new registrador(numRs);
    BitSet endRt = b.get(16,21);
    int numRt = Integer.parseInt(funcoes.bitSetStr(endRt, 5, true),2);
    this.rT = new registrador(numRt);
    BitSet endRd = b.get(11,16);
    int numRd = Integer.parseInt(funcoes.bitSetStr(endRd, 5, true),2);
    this.rD = new registrador(numRd);
    BitSet bitShmt = b.get(6,11);
    this.shmt = Integer.parseInt(funcoes.bitSetStr(bitShmt, 5, true),2);
      
    switch(funct){
      case FUNCT_SLL:{
        this.nome = "sll";
        break;
      }
      case FUNCT_JR:{
        this.nome = "jr";
        break;
      }
      case FUNCT_MULT:{
        this.nome = "mult";
        break;
      }
      case FUNCT_DIV:{
        this.nome = "div";
        break;
      }
      case FUNCT_ADD:{
        this.nome = "add";
        break;
      }
      case FUNCT_SUB:{
        this.nome = "sub";
        break;
      }
      case FUNCT_AND:{
        this.nome = "and";
        break;
      }
      case FUNCT_OR:{
        this.nome = "or";
        break;
      }
      case FUNCT_SLT:{
        this.nome = "slt";
        break;
      }
      
    }
    
    
    System.out.println(this.nome);
  }

  public int getFunct() {
    return funct;
  }

  public String getNome() {
    return nome;
  }

  public registrador getrD() {
    return rD;
  }

  public registrador getrS() {
    return rS;
  }

  public registrador getrT() {
    return rT;
  }

  public int getShmt() {
    return shmt;
  }

  @Override
  public int getOpCode() {
    return OPCODE_R;
  }
  
  public String toString(){
    return nome + " $" + rD.getEndereco() + ",$" + rS.getEndereco() + ",$" + rT.getEndereco(); 
  }
  
  
  
  
}
